package org.txazo.blog.util;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Cookie工具类
 * 
 * @author Tu XiaoZhou
 * @since 2013-08-10
 * 
 */
public class CookieUtil {

	/** Cookie默认缓存最大时间30天 */
	private static int defaultMaxAge = 2592000;
	/** Cookie分隔符 */
	private static String cookieSeparator = "^~^";
	/** 等号 */
	private static String equalSign = "=";

	/** 获取Cookie */
	public static String getCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName) {
		if (StringUtil.isNotEmpty(cookieName)) {
			Cookie[] cookies = request.getCookies();

			if (cookies != null && cookies.length > 0) {
				for (Cookie cookie : cookies) {
					if (cookieName.equals(cookie.getName())) {
						return cookie.getValue();
					}
				}
			}
		}

		return null;
	}

	/** 获取Cookie */
	public static String getCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName, String paramName) {
		if (StringUtil.isNotEmpty(cookieName)
				&& StringUtil.isNotEmpty(paramName)) {
			String cookieValue = getCookie(request, response, cookieName);
			if (StringUtil.isNotEmpty(cookieValue)) {
				int index = cookieValue.indexOf(cookieSeparator + paramName
						+ equalSign);
				if (index != -1) {
					int start = cookieValue.indexOf(equalSign, index + 1);
					int end = cookieValue.indexOf(cookieSeparator, index + 1);
					return cookieValue.substring(start + 1, end);
				}
			}
		}
		return null;
	}

	/** 设置Cookie */
	public static void setCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName, String cookieValue) {
		setCookie(request, response, cookieName, cookieValue, defaultMaxAge);
	}

	/** 设置Cookie */
	public static void setCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName,
			String cookieValue, int maxAge) {
		if (StringUtil.isNotEmpty(cookieName)
				&& StringUtil.isNotEmpty(cookieValue)) {
			Cookie cookie = new Cookie(cookieName, cookieValue);
			cookie.setDomain(ContextUtil.getDomainName());
			cookie.setPath("/");
			cookie.setMaxAge(maxAge);

			response.addCookie(cookie);
		}
	}

	/**
	 * 设置Cookie(保存之前Cookie，maxAge默认30天)
	 * 
	 * @param valueMap key-value不为空
	 */
	public static void setCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName,
			Map<String, String> valueMap) {
		setCookie(request, response, cookieName, valueMap, true, defaultMaxAge);
	}

	/**
	 * 设置Cookie(maxAge默认30天)
	 * 
	 * @param valueMap key-value不为空
	 */
	public static void setCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName,
			Map<String, String> valueMap, boolean isKeepBefore) {
		setCookie(request, response, cookieName, valueMap, isKeepBefore,
				defaultMaxAge);
	}

	/**
	 * 设置Cookie(保存之前Cookie)
	 * 
	 * @param valueMap key-value不为空
	 */
	public static void setCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName,
			Map<String, String> valueMap, int maxAge) {
		setCookie(request, response, cookieName, valueMap, true, maxAge);
	}

	/**
	 * 设置Cookie
	 * 
	 * @param valueMap key-value不为空
	 * @param isKeepBefore 是否保存之前Cookie
	 * @param maxAge 最大缓存时间
	 */
	public static void setCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName,
			Map<String, String> valueMap, boolean isKeepBefore, int maxAge) {
		if (StringUtil.isNotEmpty(cookieName) && valueMap != null
				&& valueMap.size() > 0) {
			String cookieValue = null;
			if (isKeepBefore) {
				cookieValue = getCookie(request, response, cookieName);
				if (StringUtil.isEmpty(cookieValue)) {
					cookieValue = createCookieValue(valueMap);
				} else {
					Set<Entry<String, String>> entrys = valueMap.entrySet();
					for (Entry<String, String> entry : entrys) {
						String key = entry.getKey();
						String value = entry.getValue();
						if (StringUtil.isNotEmpty(key)
								&& StringUtil.isNotEmpty(value)) {
							int index = cookieValue.indexOf(cookieSeparator
									+ key + equalSign);
							if (index != -1) {
								int next = cookieValue.indexOf(cookieSeparator,
										index + 1);
								cookieValue = cookieValue.substring(0, index)
										+ cookieSeparator
										+ key
										+ equalSign
										+ value
										+ cookieValue.substring(next,
												cookieValue.length());
							} else {
								cookieValue += key + equalSign + value
										+ cookieSeparator;
							}
						}
					}
				}
			} else {
				cookieValue = createCookieValue(valueMap);
			}

			if (StringUtil.isNotEmpty(cookieValue)) {
				Cookie cookie = new Cookie(cookieName, cookieValue);
				cookie.setDomain(ContextUtil.getDomainName());
				cookie.setPath("/");
				cookie.setMaxAge(maxAge);

				response.addCookie(cookie);
			}
		}
	}

	/** 组合Cookie */
	private static String createCookieValue(Map<String, String> valueMap) {
		StringBuilder sb = new StringBuilder("");
		Set<Entry<String, String>> entrys = valueMap.entrySet();
		for (Entry<String, String> entry : entrys) {
			String key = entry.getKey();
			String value = entry.getValue();
			if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(value)) {
				sb.append(cookieSeparator);
				sb.append(key);
				sb.append(equalSign);
				sb.append(value);
			}
		}
		if (StringUtil.isNotEmpty(sb.toString())) {
			sb.append(cookieSeparator);
		}
		return sb.toString();
	}

	/** 清除Cookie */
	public static void clearCookie(HttpServletRequest request,
			HttpServletResponse response, String cookieName) {
		if (StringUtil.isNotEmpty(cookieName)) {
			Cookie[] cookies = request.getCookies();
			for (Cookie cookie : cookies) {
				if (cookieName.equals(cookie.getName())) {
					cookie.setDomain(ContextUtil.getDomainName());
					cookie.setPath("/");
					cookie.setMaxAge(0);
					cookie.setValue(null);

					response.addCookie(cookie);
					break;
				}
			}
		}
	}

}
